package org.jtb.mensawotd;

import java.io.IOException;
import java.util.Calendar;
import java.util.TimeZone;

import org.json.JSONArray;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.SystemClock;
import android.text.Html;
import android.util.Log;
import android.widget.RemoteViews;

public class MensaWotdWidget extends AppWidgetProvider {
	@Override
	public void onUpdate(final Context context, AppWidgetManager mgr, int[] ids) {
		super.onUpdate(context, mgr, ids);
		for (final int id : ids) {
			Intent i = getStartServiceIntent(context, id);
			context.startService(i);
		}
	}

	@Override
	public void onDeleted(Context context, int[] ids) {
		super.onDeleted(context, ids);
		for (int id : ids) {
			MensaWotdWidget.cancel(context, id);
		}
	}

	static void sendUpdateWidget(Context context, int id) {
		Intent i = getUpdateWidgetIntent(context, id);
		context.sendBroadcast(i);
	}

	static void startDetails(Context context) {
		Intent i = new Intent(context, DetailsActivity.class);
		i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		context.startActivity(i);
	}

	private static Intent getUpdateWidgetIntent(Context context, int id) {
		Intent i = new Intent();
		i.setClass(context, MensaWotdWidget.class);
		i.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
		i.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[] { id });
		i.setData(Uri.parse("org.jtb.mensawotd/" + id));

		return i;
	}

	private static PendingIntent getWidgetClickPendingIntent(Context context,
			String action, int id) {
		Intent i = new Intent(context, WidgetClickReceiver.class);
		i.setAction(action);
		i.putExtra("org.jtb.mensawotd.id", id);
		i.setData(Uri.parse("org.jtb.mensawotd/" + id));
		PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
		return pi;
	}

	private static Intent getStartServiceIntent(Context context, int id) {
		Intent i = new Intent(context, UpdateService.class);
		i.putExtra("org.jtb.mensawotd.id", id);
		i.setData(Uri.parse("org.jtb.mensawotd/" + id));
		return i;
	}

	static void schedule(Context context, int id) {
		// Log.d("mensawotd", "scheduling id: " + id);

		Prefs prefs = new Prefs(context);
		WidgetState state = prefs.getState();

		Intent updateIntent = getUpdateWidgetIntent(context, id);
		PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0,
				updateIntent, PendingIntent.FLAG_CANCEL_CURRENT);
		AlarmManager alarmManager = (AlarmManager) context
				.getSystemService(Context.ALARM_SERVICE);

		if (state == WidgetState.SUCCESS) {
			// set to 00:15:00 the next day
			Calendar cal = Calendar.getInstance(TimeZone
					.getTimeZone("GMT-5:00"));
			cal.set(Calendar.HOUR_OF_DAY, 0);
			cal.set(Calendar.MINUTE, 15);
			cal.set(Calendar.SECOND, 0);
			cal.set(Calendar.MILLISECOND, 0);
			cal.add(Calendar.DAY_OF_YEAR, 1);

			long time = cal.getTimeInMillis();
			Log.d("mensawotd", "time: " + time);

			alarmManager.set(AlarmManager.RTC_WAKEUP, time, pendingIntent);
		} else {
			// re-check every 15 minutes
			alarmManager.set(AlarmManager.RTC_WAKEUP,
					System.currentTimeMillis() + 1000 * 60 * 15, pendingIntent);
		}

	}

	private static String toString(int[] ints) {
		JSONArray ja = new JSONArray();
		for (int i : ints) {
			ja.put(i);
		}
		return ja.toString();
	}

	private static void cancel(Context context, int id) {
		// Log.d("mensawotd", "cancelling id: " + id);

		Intent updateIntent = getUpdateWidgetIntent(context, id);

		PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0,
				updateIntent, PendingIntent.FLAG_CANCEL_CURRENT);
		AlarmManager alarmManager = (AlarmManager) context
				.getSystemService(Context.ALARM_SERVICE);
		alarmManager.cancel(pendingIntent);
	}

	static void update(final Context context, final int id) {
		// Log.d("mensawotd", "updating id: " + id);
		AppWidgetManager mgr = AppWidgetManager.getInstance(context
				.getApplicationContext());

		final Prefs prefs = new Prefs(context);
		prefs.setState(WidgetState.LOADING);

		RemoteViews views = new RemoteViews(context.getPackageName(),
				R.layout.widget_loading);
		mgr.updateAppWidget(id, views);

		views = buildUpdate(context, id);
		if (views == null) {
			prefs.setState(WidgetState.FAILURE);
			views = buildError(context, id);
		} else {
			prefs.setState(WidgetState.SUCCESS);
		}

		mgr.updateAppWidget(id, views);
	}

	private static RemoteViews buildError(Context context, int id) {
		RemoteViews views = new RemoteViews(context.getPackageName(),
				R.layout.widget_error);
		Intent i = getUpdateWidgetIntent(context, id);
		PendingIntent pi = getWidgetClickPendingIntent(context, "update", id);
		views.setOnClickPendingIntent(R.id.widget_layout, pi);

		return views;
	}

	private static RemoteViews buildUpdate(Context context, int id) {
		RemoteViews views = new RemoteViews(context.getPackageName(),
				R.layout.widget);

		Prefs prefs = new Prefs(context);
		Fetcher fetcher = null;

		try {
			fetcher = new Fetcher(MensaWotdUrl.TODAY);
			// fetcher = new Fetcher("http://wordsmith.org/words/riposte.html");
		} catch (IOException e) {
			Log.e("mensawotd", "widget, error fetching wotd page", e);
			return null;
		}

		MensaWotdParser parser = new MensaWotdParser(fetcher.getContent());
		if (parser.getWord() == null) {
			return null;
		}
		HistoryItem item = prefs.addHistory(parser.getWord(), parser.getUrl(),
				parser.getDate().getTime());

		views.setTextViewText(R.id.widget_word_text,
				Html.fromHtml(parser.getWord()));
		views.setTextViewText(R.id.widget_pronunciation_text,
				Html.fromHtml(parser.getPronunciation()));
		views.setTextViewText(R.id.widget_meaning_text,
				Html.fromHtml(parser.getMeaning()));
		views.setTextViewText(R.id.widget_date_text, item.getDateString(false));

		PendingIntent pi = getWidgetClickPendingIntent(context, "details", id);
		views.setOnClickPendingIntent(R.id.widget_layout, pi);

		return views;
	}
}
